#pragma once
// #include "Connection.hpp"
#include "Reactor.hpp"

using service_t = std::function<void(Connection*)>;

class HandlerConnection
{
public:
    HandlerConnection(service_t service)
        :_service(service)
    {}
    void Recv(Connection* con)
    {
        errno = 0;
        LOG(INFO, "HandlerRecv fd : %d\n", con->Socket());
        while(true)
        {
            char buff[1024];
            ssize_t n = ::recv(con->Socket(), buff, sizeof(buff) - 1, 0);
            if(n > 0)
            {
                buff[n] = 0;
                con->inbuffer() += buff;
            }
            else
            {
                if(errno == EWOULDBLOCK || errno == EAGAIN)
                {
                    break;
                }
                else if(errno == EINTR)
                {
                    continue;
                }
                else
                {
                    con->_excepter(con);
                    return ;
                }
            }
        }
        //处理输入数据
        _service(con);
    }
    void Send(Connection* con)
    {
        errno = 0;
        while(true)
        {
            ssize_t n = ::send(con->Socket(), con->outbuffer().c_str(), con->outbuffer().size(), 0);
            if(n > 0)
            {
                con->outbuffer().erase(0, n);
                if(con->outbuffer().empty())
                    break;
            }
            else
            {
                if(errno == EWOULDBLOCK || errno == EAGAIN)
                {
                    break;
                }
                else if(errno == EINTR)
                {
                    continue;
                }
                else
                {
                    con->_excepter(con);
                    return;
                }
            }
        }
        if(!con->outbuffer().empty())
        {
            con->_R->EnableReadWrite(con->Socket(), true, true);
        }
        else
        {
            con->_R->EnableReadWrite(con->Socket(), true, false);
        }
    }
    void Except(Connection* con)
    {
        errno = 0;
        LOG(DEBUG, "client quit, fd : %d\n", con->Socket());
        con->_R->RemoveConnection(con->Socket());
    }
    ~HandlerConnection()
    {}
private:
    service_t _service;
};